/*
 * @Author: Troubadour 2276791354@qq.com
 * @Date: 2024-03-22 09:34:20
 * @LastEditors: Troubadour 2276791354@qq.com
 * @LastEditTime: 2024-03-22 16:41:07
 * @FilePath: \ANR_RS01\anr_rs01.c
 * @Description:
 */

#include "anr_rs01.h"
#include <string.h>

/* Protocol length. */
#define RS01_COM_LEN (12)

/* Byte 0~1 are message headers. */
#define RS01_COM_BYTE_0 (0x55)
#define RS01_COM_BYTE_1 (0x20)
/* Byte 2~5 are the device ID. */
#define RS01_COM_BYTE_2T5(Byte2, Byte3, Byte4, Byte5)       ((Byte2 << 24) | (Byte3 << 16) | (Byte4 << 8) | Byte5)
/* Byte 6~7 are battery information and tire pressure.
 * Byte 6, bits 4 to 7 are battery level.
 * The battery level is divided into 15 levels: below
 * 1: 2.1V, 2: 2.1V to 2.2V, 3: 2.2V to 2.3V, 4: 2.3V to 2.4V, 5: : 2.4V to 2.5V,
 * 6: 2.5V to 2.6V, 7: 2.6V to 2.7V, 8: 2.7V to 2.8V, 9: 2.8V to 2.9V, 10: 2.9V to 3.0V,
 * 11: 3.0V to 3.1V, 12: 3.1V to 3.2V, 13: 3.2V to 3.3V, 14: 3.3V to 3.4V, above 15: 3.4V.
 */
#define RS01_COM_BYTE_6_BtInfo(Byte6)           ((Byte6 >> 4) & 0x0F)
/* Byte 6, bits 0 to 3 are the high bits of tire pressure, and byte 7 is the low 8 bits. Unit: Kpa. */
#define RS01_COM_BYTE_6T7_TP(Byte6, Byte7)      (((Byte6 & 0x0F) << 8) | Byte7)
/* Byte 8 are temperature. Unit: C. */
#define RS01_COM_BYTE_8_Temp(Byte8)             (Byte8)
/* Byte 9 are sensor tire number. */
#define RS01_COM_BYTE_9_Num(Byte9)              (Byte9)
/* Byte 10 are checksum. Calculation method: 0XFF-SUM(byte2~byte9) */
#define RS01_COM_BYTE_10_CheckSum(Byte10)       (Byte10)
/* Byte 11 are message tail. */
#define RS01_COM_BYTE_11                        (0x0D)

RS01_TypeDef rs01_Data[RS01_QUANTITY];

/**
 * @function: Rs01_Checksum
 * @brief:
 * @param {uint8_t} *Buffer
 * @param {uint8_t} len
 * @return {*}
 */
static uint8_t Rs01_Checksum(uint8_t *Buffer)
{
    uint16_t sum = 0;

    for (uint8_t i = 2; i < 10; i++)
    {
        sum += Buffer[i];
    }

    return (uint8_t)(0xFF - (sum & 0xFF));
}

/**
 * @function:RS01_UnpackBuffer
 * @brief Unpacking data.
 * @param {uint8_t} *DataBuff: buffer
 * @param {uint16_t} DataLen: lenght
 * @return {uint8_t} 0: OK. Other: Error
 */
uint8_t RS01_UnpackBuffer(uint8_t *DataBuff, uint16_t DataLen)
{
    static uint8_t TempBuff[128] = {0};
    static uint16_t DataCnt = 0;
    uint16_t HeadPoint = 0;
    uint32_t TempID = 0;

    if ((sizeof(TempBuff) - DataCnt) > DataLen)
    {
        memcpy(TempBuff + DataCnt, DataBuff, DataLen);
    }
    else
    {
        DataCnt = 0;
        memcpy(TempBuff, DataBuff, DataLen);
    }
    DataCnt += DataLen;

    /* Check lenght. */
    if (DataCnt < RS01_COM_LEN)
    {
        return 1;
    }

    /* Find message headers. */
    for (HeadPoint = 0; HeadPoint < DataCnt - RS01_COM_LEN + 1; HeadPoint++)
    {
        if (RS01_COM_BYTE_0 == TempBuff[HeadPoint])
        {
            if ((TempBuff[HeadPoint + 1] == RS01_COM_BYTE_1) || (TempBuff[HeadPoint + 11] == RS01_COM_BYTE_11))
            {
                break;
            }
        }
    }
    if (DataCnt - HeadPoint < RS01_COM_LEN)
    {
        return 2;
    }

    /* Checksum */
    if (Rs01_Checksum(TempBuff + HeadPoint) != RS01_COM_BYTE_10_CheckSum(TempBuff[HeadPoint + 10]))
    {
        return 4;
    }
    /* Get ID */
    TempID = RS01_COM_BYTE_2T5(TempBuff[HeadPoint + 2], TempBuff[HeadPoint + 3], TempBuff[HeadPoint + 4], TempBuff[HeadPoint + 5]);
    for (uint8_t i = 0; i < RS01_QUANTITY; i++)
    {
        if ((rs01_Data[i].id == TempID) && (rs01_Data[i].Number == RS01_COM_BYTE_9_Num(TempBuff[HeadPoint + 9])))
        {
            rs01_Data[i].BettryLevel = RS01_COM_BYTE_6_BtInfo(TempBuff[HeadPoint + 6]);
            rs01_Data[i].TirePressure = RS01_COM_BYTE_6T7_TP(TempBuff[HeadPoint + 6], TempBuff[HeadPoint + 7]);
            rs01_Data[i].Temp = RS01_COM_BYTE_8_Temp(TempBuff[HeadPoint + 8]);
            rs01_Data[i].CheckSum = RS01_COM_BYTE_10_CheckSum(TempBuff[HeadPoint + 10]);
            rs01_Data[i].UpdataFlag = 1;
            break;
        }
    }

    /* Organize data. */
    memcpy(TempBuff, TempBuff + HeadPoint + RS01_COM_LEN, DataLen);
    DataCnt = DataCnt - HeadPoint - RS01_COM_LEN;

    return 0;
}

/**
 * @function: RS01_SetBindingID
 * @brief  Used for tire number binding ID.
 * @param {uint8_t} num: Sensor tire number.
 * @param {uint32_t} id: Sensor ID.
 * @return {uint8_t} 0: OK. Other: Error.
 */
uint8_t RS01_SetBindingID(uint8_t num, uint32_t id)
{
    if (num >= RS01_QUANTITY)
    {
        return 0;
    }
    rs01_Data[num].id = id;

    return 1;
}

/**
 * @function: RS01_GetId
 * @brief Get id.
 * @param {uint8_t} num: Sensor tire number.
 * @return {uint32_t}
 */
uint32_t RS01_GetId(uint8_t num)
{
    if (num >= RS01_QUANTITY)
    {
        return 0;
    }

    return rs01_Data[num].id;
}

/**
 * @function: RS01_GetBettryLevel
 * @brief Get Level
 * @param {uint8_t} num: Sensor tire number.
 * @return {uint8_t}
 */
uint8_t RS01_GetBettryLevel(uint8_t num)
{
    if (num >= RS01_QUANTITY)
    {
        return 0;
    }

    return rs01_Data[num].BettryLevel;
}

/**
 * @function: RS01_GetBettryVoltage
 * @brief Get Bettry voltage, Less than 2.1V is a low voltage
 * @param {uint8_t} num: Sensor tire number.
 * @return {float} Bettry voltage.
 */
float RS01_GetBettryVoltage(uint8_t num)
{
    float btVol = 0;

    if (num >= RS01_QUANTITY)
    {
        return 0;
    }

    if ((rs01_Data[num].BettryLevel > 1) && (rs01_Data[num].BettryLevel <= 15))
    {
        btVol = 1.9 + (rs01_Data[num].BettryLevel * 0.1);
    }
    else
    {
        btVol = 0;
    }

    return btVol;
}

/**
 * @function: RS01_GetTirePressure
 * @brief GetTire Pressure
 * @param {uint8_t} num: Sensor tire number.
 * @return {uint16_t} 0: Error. Unit: kpa.
 */
uint16_t RS01_GetTirePressure(uint8_t num)
{
    if (num >= RS01_QUANTITY)
    {
        return 0;
    }

    return rs01_Data[num].TirePressure;
}

/**
 * @function: RS01_GetTemperature
 * @brief Get Temperature.
 * @param {uint8_t} num: Sensor tire number.
 * @return {char}
 */
char RS01_GetTemperature(uint8_t num)
{
    if (num >= RS01_QUANTITY)
    {
        return 0;
    }

    return rs01_Data[num].Temp;
}

/**
 * @function: RS01_GetChecksum
 * @brief Get Checksum.
 * @param {uint8_t} num: Sensor tire number.
 * @return {uint8_t}
 */
uint8_t RS01_GetChecksum(uint8_t num)
{
    if (num >= RS01_QUANTITY)
    {
        return 0;
    }

    return rs01_Data[num].CheckSum;
}

/**
 * @function: RS01_GetUpdataState
 * @brief Check for new data.
 * @param {uint8_t} num: Sensor tire number.
 * @return {uint8_t} If there is new data for 1, then there is no data for 0.
 */
uint8_t RS01_GetUpdataState(uint8_t num)
{
    if (num >= RS01_QUANTITY)
    {
        return 0;
    }

    if(rs01_Data[num].UpdataFlag)
    {
        rs01_Data[num].UpdataFlag = 0;
        return 1;
    }
    return 0;
}

/**
 * @function: SKU622_Init
 * @brief RS01 initialization.
 * @return {*}
 */
void RS01_Init(void)
{
    for (uint8_t i = 0; i < RS01_QUANTITY; i++)
    {
        rs01_Data[i].Number = i;
    }
}







